﻿using System.Collections.Generic;
using TrueSync;

namespace HEFramework
{
    public static class SkillEffectComponentSystem
    {
        [EntitySystem]
        public class SkillEffectComponentAwakeSystem : AwakeSystem<SkillEffectComponent>
        {
            protected override void Awake(SkillEffectComponent _self)
            {
                _self.AddChild<SkillEffectTargetComponent>();
                _self.AddChild<SkillEffectRangeComponent>();
                _self.AddChild<SkillEffectExecutionComponent>();
            }
        }

        [EntitySystem]
        public class SkillEffectComponentDestroySystem : DestroySystem<SkillEffectComponent>
        {
            protected override void Destroy(SkillEffectComponent _self)
            {
                foreach (var value in _self.NowBuffs.Values)
                {
                    ObjectGenerater.Instance.Recycle(value);
                }

                _self.AddBuffs.Clear();
                _self.NowBuffs.Clear();
                _self.RemoveBuffs.Clear();
            }
        }


        public static void Execute(this SkillEffectComponent _self, int _id, Entity _receiver, TSVector _pos)
        {
            var seec = _self.GetChild<SkillEffectExecutionComponent>();
            if (seec == null)
            {
                return;
            }

            seec.Execute(_id, _receiver, _pos);
        }

        public static void Remove(this SkillEffectComponent _self, int _id, Entity _receiver, TSVector _pos)
        {
            var seec = _self.GetChild<SkillEffectExecutionComponent>();
            if (seec == null)
            {
                return;
            }

            seec.Remove(_id, _receiver, _pos);
        }

        public static void Destroy(this SkillEffectComponent _self, int _id, Entity _receiver, TSVector _pos)
        {
            var seec = _self.GetChild<SkillEffectExecutionComponent>();
            if (seec == null)
            {
                return;
            }

            seec.Destroy(_id, _receiver, _pos);
        }

        public static SkillEffectBuff GetBuff(this SkillEffectComponent _self, int _id)
        {
            SkillEffectBuff buff;
            _self.NowBuffs.TryGetValue(_id, out buff);
            return buff;
        }

        /// <summary>
        /// 获取技能效果ID组【引用后需释放列表】
        /// </summary>
        /// <param name="_self"></param>
        /// <param name="_id"></param>
        /// <param name="_isActive"></param>
        /// <returns></returns>
        public static ListObject<int> GetEffectIDs(this SkillEffectComponent _self, int _id, bool _isActive)
        {
            //检测该技能所有效果的选择对象
            ListObject<int> ids = ListObject<int>.Create();

            var dc = _self.GetSceneChild<DataTableComponent>();

            if (dc == null)
            {
                return ids;
            }

            var sData = dc.LoadDataTable<DRSkill>().GetData(_id);

            int id;
            switch (sData.Type)
            {
                case (int)eSkillType.Passive:

                    if (!_isActive)
                    {
                        for (int i = 0; i < sData.PEffectIDs.Length; i++)
                        {
                            id = sData.PEffectIDs[i];
                            if (_self.CheckID(id))
                            {
                                ids.Add(id);
                            }
                        }
                    }

                    break;

                case (int)eSkillType.Active:

                    if (_isActive)
                    {
                        for (int i = 0; i < sData.AEffectIDs.Length; i++)
                        {
                            id = sData.AEffectIDs[i];
                            if (_self.CheckID(id))
                            {
                                ids.Add(id);
                            }
                        }
                    }

                    break;

                case (int)eSkillType.Both:

                    if (!_isActive)
                    {
                        for (int i = 0; i < sData.PEffectIDs.Length; i++)
                        {
                            id = sData.PEffectIDs[i];
                            if (_self.CheckID(id))
                            {
                                ids.Add(id);
                            }
                        }
                    }

                    if (_isActive)
                    {
                        for (int i = 0; i < sData.AEffectIDs.Length; i++)
                        {
                            id = sData.AEffectIDs[i];
                            if (_self.CheckID(id))
                            {
                                ids.Add(id);
                            }
                        }
                    }


                    break;
            }

            return ids;
        }

        private static bool CheckID(this SkillEffectComponent _self, int _id)
        {
            if (_id == 0 || _id == -1)
            {
                return false;
            }

            return true;
        }

        private static TSVector GetMainEntityPos(this SkillEffectComponent _self)
        {
            var tc = _self.GetMainEntity().GetChild<TransformComponent>();
            if (tc == null)
            {
                return new TSVector();
            }

            return tc.P;
        }

        public static Entity GetMainEntity(this SkillEffectComponent _self)
        {
            return _self.Parent.Parent;
        }
    }
}